Use case: DCMI continuous capture

Capture frames continuously from a parallel camera stream. A frame completion callback notifies the application each time a frame finishes.

Sequence diagram

Continuous capture using HAL1 DCMI + DMA APIs.

  @startuml
  hide footbox
  participant "User Application" as part1
  participant "DCMI Driver"      as part5
  participant "DMA Driver"       as part6

  group Initialization + configuration
     part1->part5 : HAL_DCMI_Init()
     part5-->part1 : HAL_OK
     part1->part5 : __HAL_LINKDMA()
     note right: link DMA handle to DCMI handle
  end

  group Process (continuous frames)
     part1->part5 : HAL_DCMI_Start_DMA()
     part5-->part1 : HAL_OK
     group Repeat per frame
        part6->part5 : DMA transfer complete callback
        part5->part1 : HAL_DCMI_FrameEventCallback()
     end
  end

  group De-initialization
     part1->part5 : HAL_DCMI_DeInit()
     part5-->part1 : HAL_OK
  end
  @enduml

Code snippet

HAL1

HAL2

#define FRAME_BUFFER_ADDR   (0x24000000U)
#define FRAME_WORDS         (640U * 480U * 2U / 4U)
DCMI_HandleTypeDef hdcmi;
DMA_HandleTypeDef hdma;



hdcmi.Instance                 = DCMI;


hdcmi.Init.JPEGMode            = DCMI_JPEG_DISABLE;
hdcmi.Init.PCKPolarity         = DCMI_PCKPOLARITY_FALLING;
hdcmi.Init.HSPolarity          = DCMI_HSPOLARITY_HIGH;
hdcmi.Init.VSPolarity          = DCMI_VSPOLARITY_HIGH;
hdcmi.Init.ExtendedDataMode    = DCMI_EXTEND_DATA_8B;


hdcmi.Init.SynchroMode         = DCMI_SYNCHRO_HARDWARE;

hdcmi.Init.CaptureRate         = DCMI_CR_ALL_FRAME;


hdcmi.Init.ByteSelectMode      = DCMI_BSM_ALL;
hdcmi.Init.ByteSelectStart     = DCMI_OEBS_ODD;
hdcmi.Init.LineSelectMode      = DCMI_LSM_ALL;
hdcmi.Init.LineSelectStart     = DCMI_OELS_ODD;
HAL_DCMI_Init(&hdcmi);
__HAL_LINKDMA(&hdcmi, DMA_Handle, hdma);

HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t*)FRAME_BUFFER_ADDR, FRAME_WORDS);

void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
}
HAL_DCMI_DeInit(&hdcmi);
#define FRAME_BUFFER_ADDR   (0x24000000U)
#define FRAME_SIZE_BYTES    (640U * 480U * 2U)
hal_dcmi_handle_t hdcmi;
hal_dma_handle_t hdma;
hal_dcmi_parallel_config_t parallel_cfg;
hal_dcmi_pipe_config_t pipe_cfg;

 HAL_DCMI_Init(&hdcmi, HAL_DCMI);
 HAL_DCMI_SetDMA(&hdcmi, &hdma);

 parallel_cfg.format = HAL_DCMI_FORMAT_UNCOMPRESSED;
 parallel_cfg.pixel_polarity = HAL_DCMI_PIXEL_CLOCK_FALLING;
 parallel_cfg.hsync_polarity = HAL_DCMI_HSYNC_HIGH;
 parallel_cfg.vsync_polarity = HAL_DCMI_VSYNC_HIGH;
 parallel_cfg.data_width = HAL_DCMI_EXTENDED_DATA_8_BITS;
 HAL_DCMI_PARALLEL_SetConfig(&hdcmi, &parallel_cfg);

 /* Synchro mode is set to HARDWARE by default */

 pipe_cfg.frame_rate = HAL_DCMI_FRAME_CAPTURE_ALL;
 HAL_DCMI_SetConfigPipe(&hdcmi, HAL_DCMI_PIPE_0, &pipe_cfg);






 HAL_DCMI_StartPipe_DMA(&hdcmi, HAL_DCMI_PIPE_0, HAL_DCMI_CAPTURE_CONTINUOUS, (uint32_t*)FRAME_BUFFER_ADDR, FRAME_SIZE_BYTES);

 void HAL_DCMI_PipeFrameEventCallback(hal_dcmi_handle_t *hdcmi, hal_dcmi_pipe_t pipe)
 {
 }
 HAL_DCMI_DeInit(&hdcmi);

Key changes

  1. HAL2 performs continuous capture through HAL_DCMI_StartPipe_DMA() instead of HAL_DCMI_Start_DMA().

  2. HAL2 provides a dedicated DMA association API (HAL_DCMI_SetDMA()) and pipe configuration APIs.

  3. Continuous-frame notifications use HAL_DCMI_PipeFrameEventCallback().